// Fill out your copyright notice in the Description page of Project Settings.


#include "SCircularArc.h"
#include "SlateOptMacros.h"

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION

void SCircularArc::Construct(const FArguments& InArgs)
{

}

END_SLATE_FUNCTION_BUILD_OPTIMIZATION

SCircularArc::SCircularArc()
	:radius(50)
	,LoopWidth(20)
	,CenterX(90)
	,CenterY(90)
	,BkColor(FLinearColor(0.01,0.05,0.36,1))
	,BeginAngle(120)
	,EndAngle(60)
	,MaXValue(500)
	,DrawValue(200)
	,DrawColor(FLinearColor(0.05,0.52,0.09,1))
	,Definition(0.5)
{
	DefaultColor.Add(FLinearColor(0.051269,0.527115,0.093059,1));//绿
	DefaultColor.Add(FLinearColor(0.760525,0.496933,0.008568,1));//黄
	DefaultColor.Add(FLinearColor(0.955973,0.417885,0.006995,1));//橙色
	DefaultColor.Add(FLinearColor(1.0,0.022174,0.0295575,1));//浅红
	DefaultColor.Add(FLinearColor(0.496933,0.036889,1,1));//紫色
	DefaultColor.Add(FLinearColor(0.434154,0.002732,0.011612,1));//深红
}

void SCircularArc::GetEllipseOuterPoint(float InCenterX, float InCenterY, float Width,float Height, float angle, FVector2D &InPoint) const
{
	float Inside_R = Width * Height / FMath::Sqrt(FMath::Pow(Width * FMath::Sin(angle), 2) + FMath::Pow(Height * FMath::Cos(angle), 2));
	InPoint.X = InCenterX + Inside_R * FMath::Cos(angle);
	InPoint.Y = InCenterY + Inside_R * FMath::Sin(angle);
}

int32 SCircularArc::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	float AngLeng = 0;
	if(BeginAngle > EndAngle)
	{
		AngLeng = 360 - BeginAngle + EndAngle;
	}
	else
	{
		AngLeng = EndAngle - BeginAngle;
	}

	//绘制背景圆弧
	for (float i = 0; i <= AngLeng; i += Definition)
	{
		float NowAng = i + BeginAngle;
		if(NowAng > 360.0)
			NowAng -= 360.0;
		
		TArray<FVector2D> points;
		float ang = M_PI * (NowAng / 180.0); //计算当前的角度


		FVector2D Point;
		GetEllipseOuterPoint(CenterX,CenterY,radius,radius,ang,Point);
		points.Add(Point);
		GetEllipseOuterPoint(CenterX,CenterY,radius + LoopWidth,radius + LoopWidth,ang,Point);
		points.Add(Point);

		FSlateDrawElement::MakeLines( //绘制线条
			OutDrawElements,
			LayerId++,
			AllottedGeometry.ToPaintGeometry(),
			points, //线条坐标
			bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, //在原色基础之上在增加别的效果
			BkColor, //显示颜色
			true, //抗锯齿
			3 //线的宽度
		);
	}

	//绘制起点和终点的圆
	FVector2D BeginPoint;
	FVector2D EndPoint;
	GetEllipseOuterPoint(CenterX,CenterY,radius + LoopWidth / 2,radius + LoopWidth / 2,M_PI * (BeginAngle / 180.0),BeginPoint);
	GetEllipseOuterPoint(CenterX,CenterY,radius + LoopWidth / 2,radius + LoopWidth / 2,M_PI * (EndAngle / 180.0),EndPoint);
	for(int i = 0; i < 360;i++)
	{
		TArray<FVector2D> points;
		float ang = M_PI * (i / 180.0); //计算当前的角度
		points.Add(BeginPoint);
		FVector2D Point;
		GetEllipseOuterPoint(BeginPoint.X,BeginPoint.Y,LoopWidth/2,LoopWidth/2,ang,Point);
		points.Add(Point);
		FSlateDrawElement::MakeLines( //绘制线条
			OutDrawElements,
			LayerId++,
			AllottedGeometry.ToPaintGeometry(),
			points, //线条坐标
			bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, //在原色基础之上在增加别的效果
			BkColor, //显示颜色
			true, //抗锯齿
			3 //线的宽度
		);

		points.Empty();
		points.Add(EndPoint);
		GetEllipseOuterPoint(EndPoint.X,EndPoint.Y,LoopWidth/2,LoopWidth/2,ang,Point);
		points.Add(Point);
		FSlateDrawElement::MakeLines( //绘制线条
			OutDrawElements,
			LayerId++,
			AllottedGeometry.ToPaintGeometry(),
			points, //线条坐标
			bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, //在原色基础之上在增加别的效果
			BkColor, //显示颜色
			true, //抗锯齿
			3 //线的宽度
		);
	}


	FLinearColor ShowColor = DrawColor;
	if(UseDefaultColor)
	{
		float AngValue = DrawValue / MaXValue;
		if(AngValue <= 0.1)
		{
			ShowColor = DefaultColor[0];
		}
		else if(AngValue <= 0.2)
		{
			ShowColor = DefaultColor[1];
		}
		else if(AngValue <= 0.3)
		{
			ShowColor = DefaultColor[2];
		}
		else if(AngValue <= 0.4)
		{
			ShowColor = DefaultColor[3];
		}
		else if(AngValue <= 0.6)
		{
			ShowColor = DefaultColor[4];
		}
		else
		{
			ShowColor = DefaultColor[5];
		}
	}
	
	//绘制的角度
	float DrawValueAng = DrawValue / MaXValue * AngLeng;
	for (float i = 0; i <= DrawValueAng; i += Definition)
	{
		float NowAng = i + BeginAngle;
		if(NowAng > 360.0)
			NowAng -= 360.0;
		
		TArray<FVector2D> points;
		float ang = M_PI * (NowAng / 180.0); //计算当前的角度


		FVector2D Point;
		GetEllipseOuterPoint(CenterX,CenterY,radius,radius,ang,Point);
		points.Add(Point);
		GetEllipseOuterPoint(CenterX,CenterY,radius + LoopWidth,radius + LoopWidth,ang,Point);
		points.Add(Point);

		FSlateDrawElement::MakeLines( //绘制线条
			OutDrawElements,
			LayerId++,
			AllottedGeometry.ToPaintGeometry(),
			points, //线条坐标
			bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, //在原色基础之上在增加别的效果
			ShowColor, //显示颜色
			true, //抗锯齿
			3 //线的宽度
		);
	}
	
	FVector2D ValueBeginPoint;
	FVector2D ValueEndPoint;
	float ValueAng = BeginAngle + DrawValueAng;
	GetEllipseOuterPoint(CenterX,CenterY,radius + LoopWidth / 2,radius + LoopWidth / 2,M_PI * (BeginAngle / 180.0),ValueBeginPoint);
	GetEllipseOuterPoint(CenterX,CenterY,radius + LoopWidth / 2,radius + LoopWidth / 2,M_PI * (ValueAng / 180.0),EndPoint);
	for(int i = 0; i < 360;i++)
	{
		TArray<FVector2D> points;
		float ang = M_PI * (i / 180.0); //计算当前的角度
		points.Add(ValueBeginPoint);
		FVector2D Point;
		GetEllipseOuterPoint(ValueBeginPoint.X,ValueBeginPoint.Y,LoopWidth/2,LoopWidth/2,ang,Point);
		points.Add(Point);
		FSlateDrawElement::MakeLines( //绘制线条
			OutDrawElements,
			LayerId++,
			AllottedGeometry.ToPaintGeometry(),
			points, //线条坐标
			bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, //在原色基础之上在增加别的效果
			ShowColor, //显示颜色
			true, //抗锯齿
			3 //线的宽度
		);

		points.Empty();
		points.Add(EndPoint);
		GetEllipseOuterPoint(EndPoint.X,EndPoint.Y,LoopWidth/2,LoopWidth/2,ang,Point);
		points.Add(Point);
		FSlateDrawElement::MakeLines( //绘制线条
			OutDrawElements,
			LayerId++,
			AllottedGeometry.ToPaintGeometry(),
			points, //线条坐标
			bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, //在原色基础之上在增加别的效果
			ShowColor, //显示颜色
			true, //抗锯齿
			3 //线的宽度
		);
	}
	return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
}
